import 'package:flutter/material.dart';

/// 以表格布局显示项目的小部件，具有特定数量的列。
///
/// 此小部件包装了ListView来创建项目行，每行包含
/// 指定数量的项目，然后换行到下一行。
///
class CollectionView<T> extends StatelessWidget {
  /// 要显示的数据项目列表。
  final List<T> items;

  /// 每行显示的项目数量。
  final int itemsPerRow;

  /// 为每个项目创建小部件的构建器函数。
  final Widget Function(BuildContext context, T item, int index) itemBuilder;

  /// 项目之间的水平间距。
  final double horizontalSpacing;

  /// 行之间的垂直间距。
  final double verticalSpacing;

  /// 整个表格周围的内边距。
  final EdgeInsetsGeometry padding;

  /// 列表是否应该以相反的方向滚动。
  final bool reverse;

  /// 底层ListView的控制器。
  final ScrollController? controller;

  /// 确定滚动视图的物理特性。
  final ScrollPhysics? physics;

  /// 滚动视图的范围是否应由内容确定。
  final bool shrinkWrap;

  const CollectionView({
    Key? key,
    required this.items,
    required this.itemsPerRow,
    required this.itemBuilder,
    this.horizontalSpacing = 8.0,
    this.verticalSpacing = 8.0,
    this.padding = EdgeInsets.zero,
    this.reverse = false,
    this.controller,
    this.physics,
    this.shrinkWrap = false,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        return ListView.separated(
          padding: padding,
          reverse: reverse,
          controller: controller,
          physics: physics ?? const AlwaysScrollableScrollPhysics(),
          shrinkWrap: shrinkWrap,
          itemCount: (items.length / itemsPerRow).ceil(),
          separatorBuilder: (context, index) =>
              SizedBox(height: verticalSpacing),
          itemBuilder: (context, rowIndex) {
            final startIndex = rowIndex * itemsPerRow;
            final endIndex = (startIndex + itemsPerRow <= items.length)
                ? startIndex + itemsPerRow
                : items.length;

            final rowItems = items.sublist(startIndex, endIndex);

            double maxWidth = constraints.maxWidth - padding.horizontal;
            final itemWidth =
                (maxWidth - (itemsPerRow - 1) * horizontalSpacing) /
                    itemsPerRow;
            return Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: List.generate(rowItems.length, (colIndex) {
                final index = startIndex + colIndex;
                return Row(
                  children: [
                    SizedBox(
                      width: itemWidth,
                      child: itemBuilder(context, rowItems[colIndex], index),
                    ),
                    Visibility(
                      visible: colIndex < rowItems.length - 1,
                      child: SizedBox(
                        width: horizontalSpacing,
                      ),
                    )
                  ],
                );
              }),
            );
          },
        );
      },
    );
  }
}

/// Example usage of [CollectionView]:
///
/// ```dart
/*
  CollectionView<String>(
    items: ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'],
    itemsPerRow: 3,
    horizontalSpacing: 10,
    verticalSpacing: 15,
    padding: EdgeInsets.all(16),
    itemBuilder: (context, item, index) {
      return Container(
        height: 100,
        color: Colors.blue[100],
        child: Center(child: Text(item)),
      );
    },
  )
*/
/// ```
